package cn.elane.kibana.demo.global.model;

import cn.elane.kibana.demo.global.util.StringUtil;
import com.alibaba.fastjson.JSONArray;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * @author Chenyu
 * @date 2019-10-30
 */
public class NameBeanUtil {
    /**
     * 只处理[{...},{...},{...}]格式的数据.
     * @param jsonStr  [{...},{...},{...}]
     * @return List<Bean>
     */
    public static List<NameBean> init2List(String jsonStr) {
        List<NameBean> list;
        if (StringUtil.ifJSONArrayStr(jsonStr)) {
            jsonStr = jsonStr.replaceAll("[\n\r]", "").replaceAll("[\t]", "    ");
            JSONArray obj = JSONArray.parseArray(jsonStr.trim());
            if (obj != null) {
                list = new ArrayList<>();
                for (Object o : obj) {
                    list.add(new NameBean(o.toString()));
                }
                return list;
            } else {
                throw new RuntimeException("json格式不正确！");
            }
        } else {
            throw new RuntimeException("json格式不正确！");
        }
    }

    public static String toJson(List<NameBean> list) {
        if (list != null && !list.isEmpty()) {
            StringBuilder sb = new StringBuilder("[");
            for (NameBean obj : list) {
                sb.append(obj.toJson().replaceAll("[\n\r]", "\\\\n")).append(",");
            }
            if (sb.toString().endsWith(",")) {
                int len = sb.length();
                sb.delete(len - 1, len);
            }
            return sb.append("]").toString();
        } else {
            return "[]";
        }
    }

    public static String toJsonObj(List<Object> list) {
        if (list != null && !list.isEmpty()) {
            StringBuilder sb = new StringBuilder("[");
            for (Object obj : list) {
                if (obj instanceof NameBean) {
                    sb.append(((NameBean) obj).toJson().replaceAll("[\n\r]", "\\\\n")).append(",");
                } else if (StringUtil.ifJSONObjectStr(obj.toString())) {
//                    sb.append(obj.toString()).append(",");
                    sb.append((new NameBean(obj.toString())).toJson().replaceAll("[\n\r]", "\\\\n")).append(",");
                } else {
                    sb.append("\"").append(obj.toString().replaceAll("[\n\r]", "\\\\n")).append("\"").append(",");
                }
            }
            if (sb.toString().endsWith(",")) {
                int len = sb.length();
                sb.delete(len - 1, len);
            }
            return sb.append("]").toString();
        } else {
            return "[]";
        }
    }

    /**
     * 指定单个name,返回一个list集合.<br>重复会被覆盖!
     *
     * @param list 集合
     * @param name 单个name
     * @return
     */
    public static List<String> toList(List<NameBean> list, String name) {
        if (list != null && list.size() > 0) {
            List<String> rs = new ArrayList<>(list.size());
            for (NameBean l : list) {
                rs.add(l.str(name));
            }
            return rs;
        }
        return null;
    }

    /**
     * 指定单个name,返回一个数组.<br>重复数据不会被覆盖!
     *
     * @param list 集合
     * @param name 单个name
     * @return
     */
    public static String[] toArray(List<NameBean> list, String name) {
        if (list != null && list.size() > 0) {
            String[] rs = new String[list.size()];
            for (int i = 0; i < list.size(); i++) {
                rs[i] = (list.get(i).str(name));
            }
            return rs;
        }
        return null;
    }

    /**
     * 将List转为Bean<br>
     * <code>[
     * {
     * "label":"对象名称",
     * "uuid":"name",
     * "object":"object"
     * },<br>
     * {
     * "label":"对象ID",
     * "uuid":"uuid",
     * "object":"object"
     * }
     * ]</code><br>
     * 根据object转为:<br>
     * <code>{
     * "object":[
     * {
     * "label":"对象名称",
     * "uuid":"name",
     * "object":"object"
     * },
     * {
     * "label":"对象ID",
     * "uuid":"uuid",
     * "object":"object"
     * }
     * ]
     * }</code><br>
     * 根据object,uuid转为:<br>
     * <code>{
     * "object":{<br>
     * "name":{
     * "label":"对象名称",
     * "uuid":"name",
     * "object":"object"
     * },<br>
     * "uuid":{
     * "label":"对象ID",
     * "uuid":"uuid",
     * "object":"object"
     * }<br>
     * }
     * }</code>
     *
     * @param list  待转list
     * @param alias 一个alias代表一个层级
     * @return Bean
     */
    public static NameBean toBean(List<NameBean> list, String... alias) {
        if (list == null || list.size() == 0 || alias == null || alias.length == 0) {
            return null;
        }
        NameBean bean = new NameBean();
        StringBuilder keyStr = new StringBuilder();
        for (NameBean obj : list) {
            keyStr.delete(0, keyStr.length());
            for (String key : alias) {
                if (keyStr.length() > 0) {
                    keyStr.append(".");
                }
                keyStr.append(obj.str(key));
            }
            bean.add(keyStr.toString(), obj);
        }
        return bean;
    }

    /**
     * 将List&lt;Map&gt转为List&lt;NameBean&gt
     *
     * @param obj
     * @return
     */
    public static List<NameBean> mapList2NameBeanList(List<Map<String, Object>> obj) {
        if (obj == null) {
            return null;
        }
        if (obj.size() == 0) {
            return new ArrayList<>();
        }
        List<NameBean> list = new ArrayList<>(obj.size());
        for (Map<String, Object> o : obj) {
            list.add(new NameBean().init(o));
        }
        return list;
    }

    /**
     * 根据上级值进行tree结构转换
     *
     * @param list 集合
     * @param id   唯一键
     * @param pId  上级唯一键
     * @param keys 需要保留的键名列表
     * @param pVal 上级值
     * @return tree集合.子级key默认为children
     */
    public static List<NameBean> toTreeList(List<NameBean> list, String id, String pId, Object pVal, String... keys) {
        if (list == null || list.size() == 0 || id == null || id.trim().length() == 0 || pId == null || pId.trim().length() == 0 || pVal == null) {
            return null;
        }
        return toTreeList(list, id, pId, pVal, (keys == null || keys.length == 0) ? null : Arrays.asList(keys));
    }

    /**
     * 根据上级值进行tree结构转换
     *
     * @param list 集合
     * @param id   唯一键
     * @param pId  上级唯一键
     * @param keys 需要保留的键名列表,null则保留所有.
     * @param pVal 上级值
     * @return tree集合.子级key默认为children
     */
    public static List<NameBean> toTreeList(List<NameBean> list, String id, String pId, Object pVal, List<String> keys) {
        if (list == null || list.size() == 0 || id == null || id.trim().length() == 0 || pId == null || pId.trim().length() == 0 || pVal == null) {
            return null;
        }
        List<NameBean> child = new ArrayList<>();
        for (NameBean l : list) {
            if (pVal.equals(l.obj(pId))) {
                if (keys != null && keys.size() > 0) {
                    child.add(l.cut(keys));
                } else {
                    child.add(l.copy());
                }
            }
        }
        if (child.size() > 0) {
            List<NameBean> temp;
            for (NameBean c : child) {
                temp = toTreeList(list, id, pId, c.obj(id), keys);
                if (temp != null) {
                    c.put("children", temp);
                }
            }
            return child;
        }
        return null;
    }

    /**
     * 将list集合转为NameBean容器
     *
     * @param list 集合
     * @param key  唯一键
     * @return NameBean
     */
    public static NameBean listToBean(List<NameBean> list, String key) {
        if (list == null || list.size() == 0 || key == null || key.trim().length() == 0) {
            return null;
        }
        NameBean rs = new NameBean();
        for (NameBean l : list) {
            rs.put(l.str(key), l);
        }
        return rs.size() > 0 ? rs : null;
    }

    /**
     * 根据指定的别名列表进行裁剪
     *
     * @param list  待裁剪的集合
     * @param alias 别名列表:key1,key2
     * @return 裁剪后的NameBean集合
     */
    public static List<NameBean> cut(List<NameBean> list, String[] alias) {
        if (list == null || list.size() == 0 || alias == null || alias.length == 0) {
            return null;
        }
        List<NameBean> rs = new ArrayList<>(list.size());
        for (NameBean l : list) {
            rs.add(l.cut(alias));
        }
        return rs;
    }

    /**
     * 根据指定的别名列表进行裁剪
     *
     * @param list  待裁剪的集合
     * @param alias 别名列表:key1
     * @return 裁剪后的String集合
     */
    public static List<String> cut(List<NameBean> list, String alias) {
        if (list == null || list.size() == 0 || alias == null || alias.trim().length() == 0) {
            return null;
        }
        List<String> rs = new ArrayList<>(list.size());
        for (NameBean l : list) {
            rs.add(l.str(alias));
        }
        return rs;
    }

    /**
     * 将NameBean-->key:NameBean格式的,转为值(NameBean)集合
     *
     * @param param 参数
     * @return NameBean集合
     */
    public static List<NameBean> valueList(NameBean param) {
        if (param == null || param.isEmpty()) {
            return null;
        }
        List<NameBean> rs = new ArrayList<>(param.size());
        param.forEach((key, val) -> rs.add((NameBean) val));
        return rs;
    }
}
